using System.Collections.Generic;
using System.Collections;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;

public partial class UICodeGenerator 
{
    public string filter_namespaces_s = "//开始引入命名空间不覆盖";
    public string filter_namespaces_e = "//结束引入命名空间不覆盖";
    public string filter_comp_s = "\t//自动生成组件每次生成都会覆盖";
    public string filter_comp_e = "\t//自动生成组件结束";
    public string filter_awake_s = "\t\t//Awake 不覆盖区域开始";
    public string filter_awake_e = "\t\t//Awake 不覆盖区域结束";
    public string filter_gen_s = "\t//自动生成组件函数实现开始";
    public string filter_gen_e = "\t//自动生成组件函数实现结束";
    public string filter_over_s = "\t//开始写入不覆盖";
    public string filter_over_e = "\t//结束写入不覆盖";
    bool is_item = false;
    StringBuilder sb = new StringBuilder();


    public string GenerateCode(ref List<CompInfo> comps,string className,string nameSpace = "",bool isItem = false,string old_code = "")
    {
        sb.Clear();
        is_item = isItem;
        string code = "";
        string headOldCode = RegexMgr.Instance.RegexBeginAndEnd(old_code,filter_namespaces_s, filter_namespaces_e);
        code += WriteHead(className,headOldCode);
        string compOldCode = RegexMgr.Instance.RegexBeginAndEnd(old_code, filter_comp_s, filter_comp_e);
        code += WriteComp(comps.ToArray(),compOldCode);
        string awakeOldCode = RegexMgr.Instance.RegexBeginAndEnd(old_code, filter_awake_s,filter_awake_e);
        code += WriteAwake(comps.ToArray(),awakeOldCode);
        string oldGenCode = RegexMgr.Instance.RegexBeginAndEnd(old_code, filter_gen_s, filter_gen_e);
        code += GenerateBindCode(comps.ToArray(),oldGenCode);
        string oldOverCode = RegexMgr.Instance.RegexBeginAndEnd(old_code, filter_over_s, filter_over_e);
        code += WriteNotCover(oldOverCode);

        code += WriteEnd();
        var ns = nameSpace.Trim();
        if(ns != "")
        {
            var temp = "";
            var sr = new StringReader(code);
            bool begin = false;
            string line = "";
            while((line = sr.ReadLine()) != null)
            {
                if(begin == false)
                {
                    temp += line + "\n";
                    if(line.Contains(filter_namespaces_e))
                    {
                        begin = true;
                        temp += "\n";
                        temp += $"namespace {ns}\n";
                        temp += "{\n";
                    }
                    
                }else 
                {
                    var len = line.Length;
                    if(len > 0)
                    {
                        temp += "\t" + line + "\n";
                    }else{
                        temp += line + "\n";
                    }
                }
            }
            temp += "}\n";
            code = temp;
        }
        return code;
    }

    string WriteHead(string className,string oldCode = "")
    {
        string class_base = is_item ? "UIItem" : "UIBase";
        string class_name = className;
        sb.AppendLine(filter_namespaces_s);
        if(oldCode == "")
        {
            sb.AppendLine("using System.Collections;");
            sb.AppendLine("using System.Collections.Generic;");
            sb.AppendLine("using UnityEngine;");
            sb.AppendLine("using UnityEngine.UI;");

        }else{
            sb.AppendLine(oldCode.Trim());
        }
        sb.AppendLine(filter_namespaces_e);
        sb.AppendLine("");
        sb.AppendLine($"public class {class_name} : {class_base}");
        sb.AppendLine("{");

        var code = sb.ToString();
        sb.Clear();
        return code;
    }

    //写入组件
    string WriteComp(CompInfo[] info,string oldCode = "")
    {
        sb.AppendLine(filter_comp_s);
        for (int i = 0; i < info.Length; i++)
        {
            // string genCode = $"\tpublic " + info[i].type + " " + info[i].name + ";";
            string genCode = $"\tpublic {info[i].type} {info[i].name};";
            if(!oldCode.Contains(genCode))
            {
                sb.AppendLine(genCode);
            }else{

            }

        }
        if(oldCode != "")
            sb.AppendLine("\t" + oldCode.Trim());

        sb.AppendLine(filter_comp_e);

        var code = sb.ToString();
        sb.Clear();
        return code;
    }

    string WriteAwake(CompInfo[] info,string oldCode = "")
    {
        sb.AppendLine("");
        sb.AppendLine("\tpublic void Awake()");
        sb.AppendLine("\t{");
        sb.AppendLine("\t\t//自动生成组件绑定函数，每次生成都会覆盖");
        sb.AppendLine("\t\tAutoBind();");
        sb.AppendLine("\t\t//自动生成组件绑定函数结束");
        sb.AppendLine("");
        sb.AppendLine(filter_awake_s);
        sb.AppendLine("\t\t" + oldCode.Trim());
        sb.AppendLine(filter_awake_e);
        sb.AppendLine("\t}");
        sb.AppendLine("");
        sb.AppendLine("\tpublic void AutoBind()");
        sb.AppendLine("\t{");
        foreach (var item in info)
        {
            string bindCode = GetBindCode(item);
            if(bindCode != "")
                sb.AppendLine(bindCode);
        }
        sb.AppendLine("\t}");

        var code = sb.ToString();
        sb.Clear();
        return code;
    }

    string GenerateBindCode(CompInfo[] info,string oldCode = "")
    {
        sb.AppendLine(filter_gen_s);
        foreach (var item in info)
        {
            var method = GetBingdingMethodCode(item,oldCode);
            if(method != "")
                sb.AppendLine(method.TrimEnd());
        }
        if(oldCode != "")
            sb.AppendLine("\t" + oldCode.Trim());

        sb.AppendLine(filter_gen_e);
        sb.AppendLine("");

        var code = sb.ToString();
        sb.Clear();
        return code;
    }

    //写入不覆盖区域
    string WriteNotCover(string oldCode = "")
    {
        sb.AppendLine(filter_over_s);
        if(oldCode != "")
        {
            sb.AppendLine("\t" + oldCode.Trim());
        }else{
            sb.AppendLine("\t//逻辑代码写在这里");
            if(is_item == false)
            {
                sb.AppendLine("\tpublic override void Refresh()");
                sb.AppendLine("\t{");
                sb.AppendLine("\t\tbase.Refresh();");
                sb.AppendLine("\t}");
            }

        }
        sb.AppendLine(filter_over_e);

        var code = sb.ToString();
        sb.Clear();
        return code;
    }

    //写入尾部
    string WriteEnd()
    {
        // sb.AppendLine("");
        sb.AppendLine("");
        sb.AppendLine("}");

        var code = sb.ToString();
        sb.Clear();
        return code;
    }
}